package com.ee.chat.api.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ee.chat.api.common.CommonService;
import com.ee.chat.api.service.IWalletService;
import com.ee.chat.common.bean.Result;
import com.ee.chat.common.dao.*;
import com.ee.chat.common.entity.*;
import com.ee.chat.common.service.IPayService;
import com.ee.chat.common.service.IYieldService;
import com.ndhutu.ee.util.DateUtil;
import com.ndhutu.ee.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Service
public class WalletServiceImpl implements IWalletService{
    private Logger log = LoggerFactory.getLogger(WalletServiceImpl.class);

    @Resource
    UserWalletMapper userWalletMapper;
    @Resource
    CommonService commonService;
    @Resource
    RechargeConfigMapper rechargeConfigMapper;
    @Resource
    UserVipMapper userVipMapper;
    @Resource
    UserRechargeLogMapper userRechargeLogMapper;
    @Resource
    SysOrderMapper sysOrderMapper;
    @Resource
    UserConsumeLogMapper userConsumeLogMapper;
    @Resource
    ExchangeConfigMapper exchangeConfigMapper;
    @Resource
    WithdrawConfigMapper withdrawConfigMapper;
    @Resource
    HostMapper hostMapper;
    @Resource
    UserCreditLogMapper userCreditLogMapper;
    @Resource
    UserWithdrawLogMapper userWithdrawLogMapper;
    @Resource
    UserMapper userMapper;
    @Resource
    UserVipLogMapper userVipLogMapper;
    @Resource
    SysConfigMapper sysConfigMapper;
    @Resource
    UserAuditLogMapper userAuditLogMapper;
    @Resource
    IYieldService yieldService;
    @Resource
    IPayService payService;
    @Resource
    UserCreditExchangeLogMapper userCreditExchangeLogMapper;

    @Value("${spring.profiles.active}")
    String active;

    @Override
    public Result getMyWallect(String token) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Integer userId = commonService.getUserId(token);
        UserWallet userWallet = userWalletMapper.getByUserId(userId);
        if(userWallet != null){
            data.put("coin", new BigDecimal(userWallet.getActiveCoin()+"").setScale(2, BigDecimal.ROUND_HALF_UP));
            data.put("credit", new BigDecimal(userWallet.getActiveCredit()+"").setScale(2, BigDecimal.ROUND_HALF_UP));
        }else{
            data.put("coin", 0);
            data.put("credit", 0);
        }

        //获取绑定支付的账户信息
        User user = userMapper.selectById(userId);
        Map<String, Object> aliPay = new HashMap<>();
        aliPay.put("name", user.getAlipayName());
        aliPay.put("no", user.getAlipayNo());
        data.put("aliPay", aliPay);

        //获取支付渠道
        Map<String, Object> pay = payService.getPayStatus(userId);
        data.put("pay", pay);

        return Result.returnSuccess(data);
    }

    @Override
    public Result getRechargePackages(String token, Integer type) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Integer group = (int)(Math.random() * Integer.parseInt(sysConfigMapper.getValue("recharge_group_num")));
        List<RechargeConfig> recharges = rechargeConfigMapper.getRecharges(type, group);
        List<Map> maps = JSONArray.parseArray(JSONObject.toJSONString(recharges), Map.class);
        for(Map map : maps){
            map.put("amount", new BigDecimal(map.get("amount")+"").divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP).doubleValue());
        }
        data.put("recharges", maps);

        return Result.returnSuccess(data);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result affirmRecharge(String token, Integer payWay, Integer packageId) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Integer userId = commonService.getUserId(token);
        RechargeConfig rechargeConfig = rechargeConfigMapper.selectById(packageId);
        if(rechargeConfig == null){
            return Result.returnFailure("套餐不存在");
        }

        //订单号
        String orderNumber = StringUtil.getOrderNumber();

        //充值记录
        UserRechargeLog rechargeLog = new UserRechargeLog();
        rechargeLog.setUserId(userId);
        rechargeLog.setOrderNumber(orderNumber);
        rechargeLog.setPayWay(payWay);
        rechargeLog.setPackageId(packageId);
        rechargeLog.setAmount(rechargeConfig.getAmount());

        UserVip vip = userVipMapper.selectValidVip(userId);
        int coin = rechargeConfig.getCoin();
        if(vip != null){
            coin += rechargeConfig.getVipGivenCoin();
        }
        if(payWay == 1){
            coin += rechargeConfig.getAliapyGivenCoin();
        }
        rechargeLog.setCoin(coin);
        rechargeLog.setStatus(0);
        userRechargeLogMapper.insert(rechargeLog);

        //统一下单
        Integer undulateAmount = rechargeConfig.getAmount();
        Integer floatRechargeFlag = Integer.parseInt(sysConfigMapper.getValue("float_recharge"));   //浮动金额
        if(floatRechargeFlag == 1){
            int random = (int)(Math.random() * 20);
            undulateAmount = rechargeConfig.getAmount() - random;
        }
        PayChannelConfig payChannelConfig = payService.getPayConfig(userId, payWay);

        String phone = null;
        User user = userMapper.selectById(userId);
        if(!StringUtil.isEmpty(user.getPhone())){
            phone = user.getPhone();
        }else{
            phone = "135"+StringUtil.getRandomNumberStr(8);
        }
        String body = "为"+phone+"充值"+((int)(rechargeLog.getAmount()/100))+"元，谨防诈骗，客服或投诉微信：ppjiyou";

        data = payService.orderHandle(userId, null, payChannelConfig.getId(), undulateAmount, orderNumber, body);
        data.put("payPattern", 0);  //原生支付
        if(payChannelConfig.getType() != 0){
            data.put("payPattern", 1);  //H5拉起支付
        }

        //系统订单
        SysOrder sysOrder = new SysOrder(userId, orderNumber, payWay, null, payChannelConfig.getId(), rechargeConfig.getAmount(), undulateAmount, 0, 0);
        sysOrderMapper.insert(sysOrder);

        return Result.returnSuccess(data);
    }

    @Override
    public Result getRechargeLog(String token, Integer page, Integer limit) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Integer userId = commonService.getUserId(token);

        Page<Map<String, Object>> p = new Page<>(page, limit);
        IPage<Map<String, Object>> iPage = userRechargeLogMapper.getRechagerLog(p, userId);
        List<Map<String, Object>> rechargeLog = iPage.getRecords();
        for(Map<String, Object> recharge : rechargeLog){
            String desc = "充值"+recharge.get("amount")+"元";
            recharge.put("desc", desc);
        }
        data.put("rechargeLog", rechargeLog);

        return Result.returnSuccess(data);
    }

    @Override
    public Result getConsumeLog(String token, Integer page, Integer limit) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Integer userId = commonService.getUserId(token);

        Page<Map<String, Object>> p = new Page<>(page, limit);
        IPage<Map<String, Object>> iPage = userConsumeLogMapper.getConsumeLogByUserId(p, userId);
        List<Map<String, Object>> consumeLog = iPage.getRecords();
        for(Map<String, Object> consume : consumeLog){
            String desc = "";
            int type = Integer.parseInt(consume.get("type")+"");
            if(type == 0){
                desc = "与"+consume.get("name")+"视频通话";
            }else if(type == 1){
                desc = "解锁"+consume.get("name")+"动态";
            }else if(type == 2){
                desc = "与"+consume.get("name")+"文字聊天";
            }else if(type == 3 || type == 4 || type == 5 || type == 6){
                desc = "赠送"+consume.get("name")+"礼物";
            }else if(type == 7){
                desc = "与"+consume.get("name")+"语音聊天";
            }else{
                desc = "其他";
            }
            consume.put("desc", desc);
        }
        data.put("consumeLog", consumeLog);

        return Result.returnSuccess(data);
    }

    @Override
    public Result getExchangePackages(String token) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Integer userId = commonService.getUserId(token);
        Host host = hostMapper.selectById(userId);

        if(host != null){
            return Result.returnFailure("主播用户不能兑换");
        }

        List<Map<String, Object>> exchanges = exchangeConfigMapper.getExchanges();

        data.put("exchanges", exchanges);
        return Result.returnSuccess(data);
    }

    @Override
    public Result getWithdrawPackages(String token) throws Exception {
        Map<String, Object> data = new HashMap<>();

        Integer userId = commonService.getUserId(token);
        Host host = hostMapper.selectByUserId(userId);

        if(host == null){
            return Result.returnFailure("非主播用户不能提现");
        }

        Integer val = 0;
//        Double rate = userCreditLogMapper.getUserInviteRegisterRate(userId);
//        if(rate >= 0.5){
//            val = 20000;
//        }
        List<Map<String, Object>> withdraws = withdrawConfigMapper.getWithdraws(val);

        data.put("withdraws", withdraws);
        return Result.returnSuccess(data);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result exchangePackage(String token, Integer packageId) throws Exception {
        Integer userId = commonService.getUserId(token);

        Host host = hostMapper.selectByUserId(userId);
        if(host != null){
            return Result.returnFailure("主播不能兑换金币");
        }

        ExchangeConfig exchangeConfig = exchangeConfigMapper.selectById(packageId);
        UserWallet userWallet = userWalletMapper.getByUserId(userId);

        if(userWallet == null || userWallet.getActiveCredit() - exchangeConfig.getCredit() < 0){
            return Result.returnFailure("积分不足，请更换其他兑换套餐");
        }

        UserCreditExchangeLog userCreditExchangeLog = new UserCreditExchangeLog(userId, packageId, exchangeConfig.getCoin(), exchangeConfig.getCredit(), 0, new Date());
        userCreditExchangeLogMapper.insert(userCreditExchangeLog);

        //添加积分扣除记录、金币增加记录
        UserCreditLog userCreditLog = new UserCreditLog(userId, userCreditExchangeLog.getId(), 3, -exchangeConfig.getCredit()*1.0, exchangeConfig.getCredit()+"积分兑换"+exchangeConfig.getCoin()+"金币");
        userCreditLogMapper.insert(userCreditLog);
//        UserCoinLog userCoinLog = new UserCoinLog(userId, 0, 3, exchangeConfig.getCoin(), exchangeConfig.getCredit()+"积分兑换"+exchangeConfig.getCoin()+"PP");
//        userCoinLogMapper.insert(userCoinLog);

        //更新用户钱包
//        userWallet.setTotalCoin(userWallet.getTotalCoin() + exchangeConfig.getCoin());
//        userWallet.setActiveCoin(userWallet.getActiveCoin() + exchangeConfig.getCoin());
        userWallet.setActiveCredit(userWallet.getActiveCredit() - exchangeConfig.getCredit());
        userWalletMapper.updateById(userWallet);

        return Result.returnSuccess(null);
    }

    /**
     * 获取积分兑换记录
     * @Author Shane
     * @Date 2019/10/6 18:56
     * @param
     * @return
     */
    @Override
    public Result getExchangeLog(String token, Integer page, Integer limit) throws Exception {
        Map<String, Object> data = new HashMap<>();
        Integer userId = commonService.getUserId(token);

        Page<Map<String, Object>> p = new Page<>(page, limit);
        IPage<Map<String, Object>> iPage = userCreditExchangeLogMapper.getCreditExchangeLogs(p, userId);
        List<Map<String, Object>> exchangeLogs = iPage.getRecords();

        data.put("exchangeLogs", exchangeLogs);
        return Result.returnSuccess(data);
    }

    @Override
    @Transactional
    public Result withdrawPackage(String token, Integer packageId, Integer way) throws Exception {
        Integer userId = commonService.getUserId(token);

        Host host = hostMapper.selectByUserId(userId);
        if(host == null){
            return Result.returnFailure("普通用户不能提现");
        }

        User user = userMapper.selectById(userId);
        if(way == 0){
            return Result.returnFailure("暂不支持微信提现，请更换为支付宝");
        }else if(way == 1){
            if(user.getAlipayName() == null || user.getAlipayNo() == null){
                return Result.returnFailure("还未绑定支付宝，请先绑定支付宝");
            }
        }else{
            return Result.returnFailure("非法参数");
        }

        WithdrawConfig withdrawConfig = withdrawConfigMapper.selectById(packageId);
        UserWallet userWallet = userWalletMapper.getByUserId(userId);

        if(userWallet.getActiveCredit() - withdrawConfig.getCredit() < 0){
            return Result.returnFailure("积分不足，请更换其他套餐提现");
        }

        Date date = new Date();
        Date beginTime = DateUtil.parse(DateUtil.format(date, "yyyy-MM-dd") + " 00:00:00", DateUtil.pattern_general);
        Date endTime = DateUtil.parse(DateUtil.format(date, "yyyy-MM-dd") + " 23:59:59", DateUtil.pattern_general);
        int count = userWithdrawLogMapper.getUserWithdrawLogCount(userId, beginTime, endTime);
        if(count >= 1){
            return Result.returnFailure("每日只可进行一次提现，今日提现次数已使用，请明日再进行操作");
        }

        //添加提现记录
        String orderNumber = StringUtil.getOrderNumber();
        UserWithdrawLog userWithdrawLog = new UserWithdrawLog(userId, 0, orderNumber, way, user.getAlipayNo(), user.getAlipayName(), packageId, withdrawConfig.getCredit().doubleValue(), withdrawConfig.getAmount(), 0);
        userWithdrawLogMapper.insert(userWithdrawLog);

        //添加系统订单
        Integer payChannelConfigId = Integer.parseInt(sysConfigMapper.getValue("remit_alipay_config_id"));
        SysOrder sysOrder = new SysOrder(userId, orderNumber, way, null, payChannelConfigId, withdrawConfig.getAmount(), 0, 1, 0);
        sysOrderMapper.insert(sysOrder);

        //更新钱包
        String desc = withdrawConfig.getCredit()+"积分提现"+(withdrawConfig.getAmount()/100.0)+"元";
        yieldService.updateUserWallet(userId, userWithdrawLog.getId(), 2, -withdrawConfig.getCredit().doubleValue(), desc, 1);

        return Result.returnSuccess(null);
    }

    @Override
    public Result getWithdrawLog(String token, Integer page, Integer limit) throws Exception {
        Map<String, Object> data = new HashMap<>();
        Integer userId = commonService.getUserId(token);

        Page<Map<String, Object>> p = new Page<>(page, limit);
        IPage<Map<String, Object>> iPage = userWithdrawLogMapper.getWithdrawLogs(p, userId);
        List<Map<String, Object>> withdrawLogs = iPage.getRecords();
        for(Map<String, Object> withdrawLog : withdrawLogs){
            String desc = "消耗"+withdrawLog.get("credit")+"积分提现";
            withdrawLog.put("desc", desc);
        }
        data.put("withdrawLogs", withdrawLogs);
        return Result.returnSuccess(data);
    }

    @Override
    public Result bindPayWay(String token, Integer way, String payNo, String payName) throws Exception {
        Integer userId = commonService.getUserId(token);

        User user = userMapper.selectById(userId);

        if(way == 0){
            return Result.returnFailure("暂未开通绑定微信功能");
        }/*else if(way == 1){
            if(user.getAlipayNo() != null || user.getAlipayName() != null){
                return Result.returnFailure("已绑定过支付宝，无需重复绑定");
            }
        }*/
        if(way > 1){
            return Result.returnFailure("非法参数");
        }

        user.setAlipayNo(payNo);
        user.setAlipayName(payName);

        //更新
        userMapper.updateById(user);

        Map<String, Object> data = new HashMap<>();
        data.put("payNo", payNo);
        data.put("payName", payName);

        return Result.returnSuccess(data);
    }

    @Override
    public Result getCreditLog(String token, Integer page, Integer limit) throws Exception {
        Integer userId = commonService.getUserId(token);
        Map<String, Object> data = new HashMap<>();

        Page<Map<String, Object>> p = new Page<>(page, limit);
        IPage<Map<String, Object>> iPage = userCreditLogMapper.getCreditLogs(p, userId);
        List<Map<String, Object>> creditLogs = iPage.getRecords();
        Iterator<Map<String, Object>> it = creditLogs.iterator();
        while (it.hasNext()){
            Map<String, Object> creditLog = it.next();
            int type = Integer.parseInt(creditLog.get("type")+"");
            int type2 = Integer.parseInt(creditLog.get("type2")+"");
            int consumId = Integer.parseInt(creditLog.get("consumId")+"");

            Integer toUserId;
            String toName, toIcon;
            String desc = null;
            User toUser = null;
            if(type == 0 || type == 6 || type == 7){
                UserConsumeLog userConsumeLog = userConsumeLogMapper.selectById(consumId);
                toUser = userMapper.selectById(userConsumeLog.getToUserId());

                if(type2 == 0){
                    if(type == 0){
                        toUser = userMapper.selectById(userConsumeLog.getUserId());
                        desc = "与"+toUser.getName()+"视频通话获得积分";
                    }else if(type == 6){
                        desc = "获取邀请的"+toUser.getName()+"主播视频通话积分的提成";
                    }else if(type == 7){
                        desc = "获取间接邀请的"+toUser.getName()+"主播视频通话的积分的二级提成";
                    }
                }else if(type2 == 1){
                    if(type == 0){
                        toUser = userMapper.selectById(userConsumeLog.getUserId());
                        desc = "动态被"+toUser.getName()+"解锁获得积分";
                    }else if(type == 6){
                        desc = "获取邀请的"+toUser.getName()+"主播动态被解锁积分的提成";
                    }else if(type == 7){
                        desc = "获取间接邀请的"+toUser.getName()+"主播动态被解锁积分的二级提成";
                    }
                }else if(type2 == 2){
                    if(type == 0){
                        toUser = userMapper.selectById(userConsumeLog.getUserId());
                        desc = "与"+toUser.getName()+"聊天获得积分";
                    }else if(type == 6){
                        desc = "获取邀请的"+toUser.getName()+"主播聊天积分的提成";
                    }else if(type == 7){
                        desc = "获取间接邀请的"+toUser.getName()+"主播聊天积分的二级提成";
                    }
                }else if(type2 == 3 || type2 == 4 || type2 == 5 || type2 == 6){
                    if(type == 0){
                        toUser = userMapper.selectById(userConsumeLog.getUserId());
                        desc = toUser.getName()+"赠送礼物获得积分";
                    }else if(type == 6){
                        desc = "获取邀请的"+toUser.getName()+"主播收到礼物积分的提成";
                    }else if(type == 7){
                        desc = "获取间接邀请的"+toUser.getName()+"主播收到礼物积分的二级提成";
                    }
                }else if(type2 == 7){
                    if(type == 0){
                        toUser = userMapper.selectById(userConsumeLog.getUserId());
                        desc = "与"+toUser.getName()+"语音聊天获得积分";
                    }else if(type == 6){
                        desc = "获取邀请的"+toUser.getName()+"主播语音聊天积分的提成";
                    }else if(type == 7){
                        desc = "获取间接邀请的"+toUser.getName()+"主播语音聊天积分的二级提成";
                    }
                }else{
                    desc = "其他";
                }
            }else if(type == 1 || type == 9){
                UserRechargeLog userRechargeLog = userRechargeLogMapper.selectById(consumId);
                toUser = userMapper.selectById(userRechargeLog.getUserId());
                if(type == 1){
                    desc = "邀请的用户"+toUser.getName()+"充值获得提成积分";
                }else{
                    desc = "间接邀请的用户"+toUser.getName()+"充值获得提成积分";
                }
            }else if(type == 2){
                desc = "提现消耗";
            }else if(type == 3){
                double credit = Double.parseDouble(creditLog.get("credit")+"");
                if(credit > 0){
                    desc = "驳回积分兑换金币退回";
                }else{
                    desc = "积分兑换成金币消耗";
                }
            }else if(type == 4){
                desc = "后台充值";
            }else if(type == 5){
                desc = "提现被驳回退回";
            }else if(type == 8){
                UserAuditLog userAuditLog = userAuditLogMapper.selectById(consumId);
                toUser = userMapper.selectById(userAuditLog.getUserId());
                desc = "邀请的用户"+toUser.getName()+"认证成功获得奖励积分";
            }else if(type == 10){
                UserVipLog userVipLog = userVipLogMapper.selectById(consumId);
                toUser = userMapper.selectById(userVipLog.getUserId());
                desc = "邀请的用户"+toUser.getName()+"充值会员获得积分";
            }else if(type == 11){
                toUser = userMapper.selectById(consumId);
                desc = "直接邀请"+toUser.getName()+"注册获得积分";
            }else{
                desc = "其他";
            }
            if(toUser == null){
                toUser = userMapper.selectById(userId);
            }

            toUserId = toUser.getId();
            toName = toUser.getName();
            toIcon = toUser.getIcon();
            creditLog.put("userId", toUserId);
            creditLog.put("name", toName);
            creditLog.put("icon", toIcon);
            creditLog.remove("type2");
            creditLog.put("desc", desc);
        }

        data.put("creditLogs", creditLogs);
        return Result.returnSuccess(data);
    }
}
